# -*- coding: utf-8 -*-

from copy import deepcopy
from xml.etree.ElementTree import * # python2.5~

CONTENT = ['$BL>;l(B', '$BF0;l(B']


# ----------------------------------------------
# Class of infomation of the morpheme.
#   attr: attributes of the morpheme
#   pred: information of predicate-argument
#   modal: information of modality
# ----------------------------------------------
class Token:
    def __init__(self, elem):
        self.attr = dict(elem.items())
        self.pred = dict()
        self.modal = dict()

        for e in list(elem):
            
            if e.tag == 'Predicate':
                self.pred = dict(e.items())
                
            elif e.tag == 'Modality':
                self.modal = dict(e.items())

    def isPred(self):
        return bool(self.pred)

    def isContent(self):
        if self.attr['pos'] in CONTENT:
            return True
        else:
            return False


# -----------------------------------------------------
# Class of infomation of chunks
#   attr: attributes of the chunk
#   toks: list of morphemes
#   head(): get index of the head chunk
#   find(): get index of the morpheme match with attr
# -----------------------------------------------------
class Chunk:
    def __init__(self, elem):
        self.attr = dict(elem.items())
        self.toks = []
        
        for tok in list(elem):
            if tok.tag == 'Token':
                self.toks.append(Token(tok))
                

    def head(self):
        return int(self.attr['head'][1:])


    def find(self, attr):
        for i, tok in enumerate(self.toks):
            for key, value in attr.iteritems():
                if not tok.attr.has_key(key):
                    break
                elif tok.attr[key] != value:
                    break
            else:
                return i
        return -1


# -----------------------------------------
# Class of information of sentence
#   attr: information of the senetence
#   chks: list of chunks
# -----------------------------------------
class Sentence:
    def __init__(self, elem):
        self.attr = dict(elem.items())
        self.chunks = []
        self.annotation = []
        
        for e in list(elem):
            
            if e.tag == 'Annotation':
                an = dict(list(e))
                self.annotation.append(an)
                
            elif e.tag == 'Chunk':
                self.chunks.append(Chunk(e))


    def getHeadChunk(self, chk_idx):
        head = self.chunks[chk_idx].head()
        
        if head != -1:
            return self.chunks[head]
        else:
            return False


    def itertokens(self):
        for chk in self.chunks:
            for tok in chk.toks:
                yield tok


    def iterchunks(self):
        chk_surfs = []
        for chk in self.chunks:
            chk_surf = ''
            for tok in chk.toks:
                chk_surf += tok.attr['surf']
            yield chk_surf


    def find_token(self, attr):
        for i, chk in enumerate(self.chunks):
            idx = chk.find(attr)
            if idx >= 0:
                return (i, idx)
        return False


# ------------------------------------------------------------
# Class of pair of the sentence
#   attr : attributes of the sentence pair
#   texts: list of text (text is list of Sentence instance)
# ------------------------------------------------------------
class Pair:
    def __init__(self, elem):
        self.attr = dict(elem.items())
        self.text = Sentence(list(list(elem)[0])[0])
        self.hypo = Sentence(list(list(elem)[1])[0])


    def iterchunks(self, idx):
        for sent in self.texts[idx]:
            for chk in sent.chunks:
                yield chk


    def itertokens(self, idx):
        for sent in self.texts[idx]:
            for tok in sent.itertokens():
                yield tok


    def reversed(self):
        out = deepcopy(self)
        out.text = deepcopy(self.hypo)
        out.hypo = deepcopy(self.text)
        return out


# -------------------------------------------------
# read xml file and return list of Pair instance
# -------------------------------------------------
def readXML(filename):
    print 'start read-xml :', filename
    
    tree = parse(filename)
    elem = tree.getroot()

    print 'complete read-xml.'
    
    return [Pair(e) for e in list(elem)]
